#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #include <iostream>
// using namespace std;

#define MAX_LINE 65
int size;
char inputTexts[100][65];
int input[100][64];

//============================================================================================================================
// 生成子密钥

/*
 * 输入：一个56位的数组 
 * 输出：两个28位的数组Ci 和 Di
 * 
 */ 
void change_1(int in[], int out1[], int out2[]) {
    for (int i = 0; i < 28; ++i) {
        out1[i] = in[i];
    }

    for (int i = 28; i < 56; ++i) {
        out2[i-28] = in[i];
    }
}

/*
 void test_change_1() {
    int in[56];
    for (int i = 0; i < 56; ++i) {
        in[i] = i + 1;
    }

    int out1[28], out2[28];
    change_1(in, out1, out2);
    cout << " test for change_1 " << endl;
    cout << " out1: ";
    for (int i = 0; i < 28; ++i) {
        cout << out1[i] << " ";
    }
    cout << endl << " out2: ";
    for (int i = 0; i < 28; ++i) {
        cout << out2[i] << " ";
    }
}
*/

/*
 * 输入：两个28位的数组Ci 和 Di
 * 输出：一个56位的数组
 * 
 */ 
void change_2(int in1[], int in2[], int out[]) {
    for (int i = 0; i < 28; ++i) {
        out[i] = in1[i];
    }

    for (int i = 28; i < 56; ++i) {
        out[i] = in2[i-28];
    }
}

/*
void test_change_2() {
    int in1[28];
    for (int i = 0; i < 28; ++i) {
        in1[i] = i + 1;
    }
    int in2[28];
    for (int i = 0; i < 28; ++i) {
        in2[i] = i + 29;
    }
    int out[56];
    change_2(in1, in2, out);
    cout << " test for change_2 " << endl;
    for (int i = 0; i < 56; ++i) {
        cout << out[i] << " ";
    }
}
*/



/*
 * PC-1置换
 * 输入，64位密钥K
 * 输出：56位有效位
 *
 */
void PC_1(int K[], int res[]) {
    int index1 = 56; //前半段的首个下标编号
    int index2 = 62; //后半段的首个下标编号
    int index3 = 27; //最后四个起始下标
    for (int i = 0; i < 28; ++i) {
        res[i] = K[index1];
        if (index1 < 7) {
            index1 = index1 + 65;
        }
        index1 = index1 - 8;
    }

    for (int i = 28; i < 52; i++) {
        res[i] = K[index2];
        if (index2 < 8) {
            index2 = index2 + 63;
        }
        index2 = index2 - 8;
    }

    for (int i = 52; i < 56; ++i) {
        res[i] = K[index3];
        index3 = index3 - 8;
    }

    //test for PC-1置换
    // for (int i = 0; i < 56; ++i) {
    //     cout << res[i] << " ";
    // }
}

/*
void test_PC_1() {
    int K[64];
    for (int i = 0; i < 64; ++i) {
        K[i] = i + 1;
    } 
    int res[56];
    PC_1(K, res);
    cout << " test for PC_1 ---------------------------" << endl;
    for (int i = 0; i < 56; ++i) {
        cout << res[i] << " ";
    }
}
*/


/*
 *计算 Ci = LSi(Ci-1) 和 Di = LSi(Di-1)，LSi(A) 表示将二进制串 A 循环左移一个位置；
 * 
 */
void left_1(int c_in[], int d_in[], int c_out[], int d_out[]) {
    //Ci
    for (int i = 0; i < 28; ++i) {
        if (i == 27) {
            c_out[i] = c_in[0];
            continue;
        }
        c_out[i] = c_in[i+1];
    }

    //Di
    for (int i = 0; i < 28; ++i) {
        if (i == 27) {
            d_out[i] = d_in[0];
            continue;
        }
        d_out[i] = d_in[i+1];
    }
}

/*
void test_left_1() {
    int c_in[28] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
    int d_in[28] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
    int c_out[28], d_out[28];
    left_1(c_in, d_in, c_out, d_out);
    cout << " test for left_1 --------------------------" << endl;
    for (int i = 0; i < 28; ++i) {
        cout << c_out[i] << " ";
    }
    cout << endl;

    for (int i = 0; i < 28; ++i) {
        cout << d_out[i] << " ";
    }
}
*/

/*
 *计算 Ci = LSi(Ci-1) 和 Di = LSi(Di-1)，LSi(A) 表示将二进制串 A 循环左移两个位置；
 * 
 */
void left_2(int c_in[], int d_in[], int c_out[], int d_out[]) {
    //Ci
    for (int i = 0; i < 28; ++i) {
        if (i == 26) {
            c_out[i] = c_in[0];
            continue;
        }
        if (i == 27) {
            c_out[i] = c_in[1];
            continue;
        }
        c_out[i] = c_in[i+2];
    }

    //Di
    for (int i = 0; i < 28; ++i) {
        if (i == 26) {
            d_out[i] = d_in[0];
            continue;
        }
        if (i == 27) {
            d_out[i] = d_in[1];
            continue;
        }
        d_out[i] = d_in[i+2];
    }
}

/*
void test_left_2() {
    int c_in[28] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
    int d_in[28] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28};
    int c_out[28], d_out[28];
    left_2(c_in, d_in, c_out, d_out);
    cout << " test for left_2 --------------------------" << endl;
    for (int i = 0; i < 28; ++i) {
        cout << c_out[i] << " ";
    }
    cout << endl;

    for (int i = 0; i < 28; ++i) {
        cout << d_out[i] << " ";
    }
}
*/

/*
 * PC-2置换
 * 输入：56位的CiDi
 * 输出：48位的Ki
 * 
 */ 
int PC2_table[48] = {14, 17, 11, 24, 1, 5, 3, 28,
                     15, 6, 21, 10, 23, 19, 12, 4,
                     26, 8, 16, 7, 27, 20, 13, 2,
                     41, 52, 31, 37, 47, 55, 30, 40,
                     51, 45, 33, 48, 44, 49, 39, 56,
                     34, 53, 46, 42, 50, 36, 29, 32
};

void PC_2(int in[], int out[]) {
    for (int i = 0; i < 48; ++i) {
        int index = PC2_table[i] - 1;
        out[i] = in[index];
    }
}

/*
void test_PC_2() {
    int in[56];
    for (int i = 0; i < 56; ++i) {
        in[i] = i + 1;
    }
    int out[48];
    PC_2(in, out);
    cout << " test for PC_2 " << endl;
    for (int i = 0; i < 48; ++i) {
        cout << out[i] << " ";
    }
}
*/

/*
 * 生成子密钥
 * 输入：64位密钥K
 * 输出：16个48位的子密钥K1-K16
 * 
 * 
 */
void generate_key(int K[], int res[][48]) {
    int PC1_res[56];
    PC_1(K, PC1_res);

    // for (int i = 0; i < 56; ++i) {
    //     cout << PC1_res[i] << " ";
    // }
    // cout << endl;

    //PC2从C[1]和D[1]开始
    int C[17][28], D[17][28];
    change_1(PC1_res, C[0], D[0]);

    // for (int i = 0; i < 28; ++i) {
    //     cout << C[0][i] << " ";
    // }
    // cout << endl;

    for (int i = 1; i < 17; ++i) {
        if (i == 1 || i == 2 || i == 9 || i == 16) {
            left_1(C[i-1], D[i-1], C[i], D[i]);
        }
        else {
            left_2(C[i-1], D[i-1], C[i], D[i]);
            // cout << " left_2 " << endl;
        }

        // cout << "==========" <<  i  << "==============" << endl;
        // for (int j = 0; j < 28; ++j) {
        //     cout << C[i][j] << " ";
        // }   
        // cout << endl;
    }

     int change_2_result[16][56];
     for (int i = 1; i < 17; ++i) {
        change_2(C[i], D[i], change_2_result[i-1]);
        PC_2(change_2_result[i-1], res[i-1]);
     }

    //  for (int i = 0; i < 16; ++i) {
    //      cout << "================ key " << i + 1 << " ===================" << endl;
    //      for (int j = 0; j < 48; ++j) {
    //          cout << res[i][j] << " ";
    //      }
    //      cout << endl;
    //  }
}

//======================================================================================

//Feistel轮函数

/* 
 * E-扩展
 * 输入：32位数组
 * 输出：48位数组
 */
int E_extend_table[48] = { 32, 1, 2, 3, 4, 5,
                           4, 5, 6, 7, 8, 9, 
                           8, 9, 10, 11, 12, 13,
                           12, 13, 14, 15, 16, 17,
                           16, 17, 18, 19, 20, 21,
                           20, 21, 22, 23, 24, 25, 
                           24, 25, 26, 27, 28, 29,
                           28, 29, 30, 31, 32, 1

};

void E_extend(int in[], int out[]) {
    for (int i = 0; i < 48; ++i) {
        int index = E_extend_table[i] - 1;
        out[i] = in[index];
    }
}

/*
void test_E_extend() {
    int in[32];
    for (int i = 0; i < 32; ++i) {
        in[i] = i + 1;
    }
    int out[48];
    E_extend(in, out);
    cout << " test for E_extend " << endl;
    for (int i = 0; i < 48; ++i) {
        cout << out[i] << " ";
    }
}
*/

/*
 * 将 E(Ri-1) 和长度为48位的子密钥 Ki 作48位二进制串按位异或运算。
 * 输入：两个48位数组
 * 输出：一个48位数组
 */ 
void XOR(int in1[], int in2[], int out[]) {
    for (int i = 0; i < 48; ++i) {
        out[i] = in1[i] ^ in2[i];
    }
}

/*
void test_XOR() {
    int in1[48], in2[48];
    for (int i = 0; i < 48; ++i) {
        in1[i] = 1;
        in2[i] = 1;
    }
    int out[48];
    XOR(in1, in2, out);
    cout << " test for XOR " << endl;
    for (int i = 0; i < 48; ++i) {
        cout << out[i] << " ";
    }
}
*/

/*
 * 将一个48位的数组平均分成8个分组，每个分组长度6位
 * 输入：一个48位数组
 * 输出：8个6位的数组
 */ 
void split(int in[], int out[][6]) {
    int j = 0;
    int temp;
    for (int i = 0; i < 48; ++i) {
        if (i % 6 == 0 && i != 0) {
            j++;
        }
        temp = i % 6;
        out[j][temp] = in[i];
    }
}

/*
void test_spilt() {
    int in[48];
    for (int i = 0; i < 48; ++i) {
        in[i] = i + 1;
    }
    int out[8][6];
    split(in, out);
    cout << " test for spilt " << endl;
    for (int i = 0; i < 8; ++i) {
        for (int j = 0; j < 6; ++j) {
            cout << out[i][j] << " ";
        }
        cout << endl;
    }
}
*/

/*
 * 十进制转4位二进制
 * 输入：一个十进制数
 * 输出：4位数组
 */ 
void d_to_b(int in, int out[]) {
    for (int i = 3; i > -1; --i) {
        out[i] = in % 2;
        in = in / 2;
    }
}

/*
void test_d_to_b() {
    int in = 14;
    int out[4];
    d_to_b(in, out);
    cout << " test for d_to_b " << endl;
    for (int i = 0; i < 4; ++i) {
        cout << out[i] << " ";
    }
}
*/

/*
 * 各个分组分别经过8个不同的 S-盒进行 6-4 转换，
 * 得到8个长度分别为4位的分组；
 * 输入：一个48位数组
 * 输出：8个长度为4位的数组
 */ 
int S1[64] = { 14, 4, 13, 1, 2, 15, 11, 8,
               3, 10, 6, 12, 5, 9, 0, 7,
               0, 15, 7, 4, 14, 2, 13, 1,
               10, 6, 12, 11, 9, 5, 3, 8,
               4, 1, 14, 8, 13, 6, 2, 11, 
               15, 12, 9, 7, 3, 10, 5, 0,
               15, 12, 8, 2, 4, 9, 1, 7, 
               5, 11, 3, 14, 10, 0, 6, 13
};

int S2[64] = { 15, 1, 8, 14, 6, 11, 3, 4, 
               9, 7, 2, 13, 12, 0, 5, 10,
               3, 13, 4, 7, 15, 2, 8, 14,
               12, 0, 1, 10, 6, 9, 11, 5,
               0, 14, 7, 11, 10, 4, 13, 1,
               5, 8, 12, 6, 9, 3, 2, 15,
               13, 8, 10, 1, 3, 15, 4, 2,
               11, 6, 7, 12, 0, 5, 14, 9
};

int S3[64] = { 10, 0, 9, 14, 6, 3, 15, 5,
               1, 13, 12, 7, 11, 4, 2, 8, 
               13, 7, 0, 9, 3, 4, 6, 10,
               2, 8, 5, 14, 12, 11, 15, 1,
               13, 6, 4, 9, 8, 15, 3, 0,
               11, 1, 2, 12, 5, 10, 14, 7,
               1, 10, 13, 0, 6, 9, 8, 7,
               4, 15, 14, 3, 11, 5, 2, 12
};

int S4[64] = { 7, 13, 14, 3, 0, 6, 9, 10, 
               1, 2, 8, 5, 11, 12, 4, 15, 
               13, 8, 11, 5, 6, 15, 0, 3,
               4, 7, 2, 12, 1, 10,14, 9,
               10, 6, 9, 0, 12, 11, 7, 13,
               15, 1, 3, 14, 5, 2, 8, 4,
               3, 15, 0, 6, 10, 1, 13, 8,
               9, 4, 5, 11, 12, 7, 2, 14
};

int S5[64] = { 2, 12, 4, 1, 7, 10, 11, 6,
               8, 5, 3, 15, 13, 0, 14, 9,
               14, 11, 2, 12, 4, 7, 13, 1, 
               5, 0, 15, 10, 3, 9, 8, 6,
               4, 2, 1, 11, 10, 13, 7, 8, 
               15, 9, 12, 5, 6, 3, 0, 14,
               11, 8, 12, 7, 1, 14, 2, 13,
               6, 15, 0, 9, 10, 4, 5, 3
};

int S6[64] = { 12, 1, 10, 15, 9, 2, 6, 8,
               0, 13, 3, 4, 14, 7, 5, 11,
               10, 15, 4, 2, 7, 12, 9, 5, 
               6, 1, 13, 14, 0, 11, 3, 8,
               9, 14, 15, 5, 2, 8, 12, 3, 
               7, 0, 4, 10, 1, 13, 11, 6,
               4, 3, 2, 12, 9, 5, 15, 10,
               11, 14, 1, 7, 6, 0, 8, 13
};

int S7[64] = { 4, 11, 2, 14, 15, 0, 8, 13,
               3, 12, 9, 7, 5, 10, 6, 1,
               13, 0, 11, 7, 4, 9, 1, 10,
               14, 3, 5, 12, 2, 15, 8, 6,
               1, 4, 11, 13, 12, 3, 7, 14, 
               10, 15, 6, 8, 0, 5, 9, 2,
               6, 11, 13, 8, 1, 4, 10, 7, 
               9, 5, 0, 15, 14, 2, 3, 12
};

int S8[64] = { 13, 2, 8, 4, 6, 15, 11, 1,
               10, 9, 3, 14, 5, 0, 12, 7,
               1, 15, 13, 8, 10, 3, 7, 4,
               12, 5, 6, 11, 0, 14, 9, 2,
               7, 11, 4, 1, 9, 12, 14, 2, 
               0, 6, 10, 13, 15, 3, 5, 8,
               2, 1, 14, 7, 4, 10, 8, 13,
               15, 12, 9, 0, 3, 5, 6, 11
};



void SC(int in[], int out[][4]) {
    int split_res[8][6];
    split(in, split_res);
    for (int i = 0; i < 8; ++i) {
        int a1 = split_res[i][0];
        int a2 = split_res[i][5];
        int b1 = split_res[i][1];
        int b2 = split_res[i][2];
        int b3 = split_res[i][3];
        int b4 = split_res[i][4];
        int n = a1 * 2 + a2;
        int m = b1 * 8 + b2 * 4 + b3 * 2 + b1;
        int index = n * 16 + m;
       if (i == 0) {
           int res = S1[index];
           d_to_b(res, out[0]);
           continue;
       }
       if (i == 1) {
           int res = S2[index];
           d_to_b(res, out[1]);
           continue;
       }
       if (i == 2) {
           int res = S3[index];
           d_to_b(res, out[2]);
           continue;
       }
       if (i == 3) {
           int res = S4[index];
           d_to_b(res, out[3]);
           continue;
       }
       if (i == 4) {
           int res = S5[index];
           d_to_b(res, out[4]);
           continue;
       }
       if (i == 5) {
           int res = S6[index];
           d_to_b(res, out[5]);
           continue;
       }
       if (i == 6) {
           int res = S7[index];
           d_to_b(res, out[6]);
           continue;
       }
       if (i == 7) {
           int res = S8[index];
           d_to_b(res, out[7]);
           continue;
       }
    }
}

/*
void test_SC() {
    int in[48];
    for (int i = 0; i < 48; ++i) {
        in[i] = 1;
    }
    int out[8][4];
    SC(in, out);
    cout << " test for SC " << endl;
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 4; ++j) {
            cout << out[i][j] << " ";
        }
        cout << endl;
    }
}
*/

/*
 * 将SC得到的结果顺序连接得到长度为32位的串；
 * 输入：8个4位数组
 * 输出：1个32位数组
 */ 

void connect1(int in[][4], int out[]) {
    int j = 0;
    for (int i = 0; i < 32; ++i) {
        if (i % 4 == 0 && i != 0) {
            j++;
        }
        int index = i % 4;
        out[i] = in[j][index];
    }
}

/*
void test_connect1() {
    int in[8][4];
    for (int i = 0; i < 8; ++i) {
        for (int j = 0; j < 4; ++j) {
            if (j % 2) in[i][j] = 1;
            else in[i][j] = 0;
        }
    }
    int out[32];
    connect1(in, out);
    cout << " test for connect1 " << endl;
    for (int i = 0; i < 32; ++i) {
        cout << out[i] << " ";
    }
}
*/

/*
 * P-置换
 * 输入：32位数组
 * 输出：重排后的32位数组：
 */ 
int P_table[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 
                    1, 15, 23, 26, 5, 18, 31, 10,
                    2, 8, 24, 14, 32, 27, 3, 9,
                    19, 13, 30, 6, 22, 11, 4, 25  
};

void P(int in[], int out[]) {
    for (int i = 0; i < 32; ++i) {
        int index = P_table[i] - 1;
        out[i] = in[index];
    }
}

/*
void test_P() {
    int in[32];
    for (int i = 0; i < 32; ++i) {
        in[i] = i + 1;
    }
    int out[32];
    P(in, out);
    cout << " test for P " << endl;
    for (int i = 0; i < 32; ++i) {
        cout << out[i] << " ";
    }
}
*/

/*
 * Feistel轮函数
 * 输入：一个长度位32位的数组， 一个长度位48位的数组
 * 输出：一个32位的数组
 */ 
void Feistel(int in1[], int in2[], int out[]) {
    int E_res[48];
    E_extend(in1, E_res);
    int XOR_res[48];
    XOR(E_res, in2, XOR_res);
    int SC_res[8][4];
    SC(XOR_res, SC_res);
    int connect1_res[32];
    connect1(SC_res, connect1_res);
    P(connect1_res, out);
}

//============================================================================================


//=================================================================================================================

// 初始置换IP

/*
 * 初始置换IP，重排64位二进制串
 * 输入：64位数组
 * 输出：重排后的64位数组
 */ 
int IP_table[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
                     60, 52, 44, 36, 28, 20, 12, 4,
                     62, 54, 46, 38, 30, 22, 14, 6,
                     64, 56, 48, 40, 32, 24, 16, 8,
                     57, 49, 41, 33, 25, 17, 9, 1,
                     59, 51, 43, 35, 27, 19, 11, 3, 
                     61, 53, 45, 37, 29, 21, 13, 5,
                     63, 55, 47, 39, 31, 23, 15, 7

};

void IP(int in[], int out[]) {
    for (int i = 0; i < 64; ++i) {
        int index = IP_table[i] - 1;
        out[i] = in[index];
    }
}

/*
void test_IP() {
    int in[64];
    for (int i = 0; i < 64; ++i) {
        in[i] = i + 1;
    }
    int out[64];
    IP(in, out);
    cout << " test for IP " << endl;
    for (int i = 0; i < 64; ++i) {
        cout << out[i] << " ";
    }
}
*/


//==================================================================================================================

//16轮迭代

/*
 * 赋值
 * 输入：一个32位数组
 * 输出: 一个32位数组
 */ 
void assign(int in[], int out[]) {
    for (int i = 0; i < 32; ++i) {
        out[i] = in[i];
    }
}

/*
void test_assign() {
    int in[32];
    for (int i = 0; i < 32; ++i) {
        in[i] = i + 1;
    }
    int out[32];
    assign(in, out);
    cout << " test for assign " << endl;
    for (int i = 0; i < 32; ++i) {
        cout << out[i] << " ";
    }
}
*/


/*
 * 加密迭代
 * 输入： 64位数组L0R0, 64位密钥K
 * 输出： 64位数组L16R16
 */

void interate_en(int in[], int K[], int out[]) {
    int L0[32], R0[32];
    for (int i = 0; i< 64; ++i) {
        if (i < 32) {
            L0[i] = in[i];
        }

        else {
            R0[i-32] = in[i];
        }
    }
    int L16[32], R16[32];
    int Key[16][48];
    generate_key(K, Key);
    int Feistel_res[32];
    for (int i = 0; i < 16; ++i) {
        assign(R0, L16);
        Feistel(R0, Key[i], Feistel_res);
        for (int j = 0; j < 32; ++j) {
            R16[j] = L0[j] ^ Feistel_res[j];
        }

        assign(L16, L0);
        assign(R16, R0);
    }
    for (int i = 0; i < 64; ++i) {
        if (i < 32) {
            out[i] = L0[i];
        }
        else {
            out[i] = R0[i-32];
        }
    }
}

/*
void test_interate_en() {
    int in[64];
    for (int i = 0; i < 64; ++i) {
        in[i] = 0;
    }
    int out[64];
    int K[64];
    interate_en(in, K, out);
    cout << " test for interate_en " << endl;
    for (int i = 0; i < 64; ++i) {
        cout << out[i] << " ";
    }
}
*/

/*
 * 解密迭代
 * 输入： 64位数组L0R0, 64位密钥K
 * 输出： 64位数组L16R16
 */

void interate_de(int in[], int K[], int out[]) {
    int L0[32], R0[32];
    for (int i = 0; i< 64; ++i) {
        if (i < 32) {
            L0[i] = in[i];
        }

        else {
            R0[i-32] = in[i];
        }
    }
    int L16[32], R16[32];
    int Key[16][48];
    generate_key(K, Key);
    int Feistel_res[32];
    for (int i = 15; i > -1; --i) {
        assign(R0, L16);
        Feistel(R0, Key[i], Feistel_res);
        for (int j = 0; j < 32; ++j) {
            R16[j] = L0[j] ^ Feistel_res[j];
        }

        assign(L16, L0);
        assign(R16, R0);
    }

    for (int i = 0; i < 64; ++i) {
        if (i < 32) {
            out[i] = L0[i];
        }
        else {
            out[i] = R0[i-32];
        }
    }
}

/*
void test_interate_de() {
    int in[64];
    for (int i = 0; i < 64; ++i) {
        in[i] = 0;
    }
    int out[64];
    int K[64];
    interate_de(in, K, out);
    cout << " test for interate_de " << endl;
    for (int i = 0; i < 64; ++i) {
        cout << out[i] << " ";
    }
}
*/



//==================================================================================================

//交换置换W
/*
 * 交换置换W，将L16R16左右交换输出R16L16
 * 输入：64位数组
 * 输出：交换后的64位数组
 */ 
void W(int in[], int out[]) {
    for (int i = 0; i < 32; ++i) {
        out[i] = in[i+32];
    }
    for (int i = 32; i < 64; ++i) {
        out[i] = in[i-32];
    }
}

/*
void test_W() {
    int in[64];
    for (int i = 0; i < 64; ++i) {
        in[i] = i + 1;
    }
    int out[64];
    W(in, out);
    cout << " test for W " << endl;
    for (int i = 0; i < 64; ++i) {
        cout << out[i] << " ";
    }
}
*/



//============================================================================================================

//逆置换IP-1

//==============================================================================================================
/*
 * 逆置换IP-1，重排64位二进制串
 * 输入：64位数组
 * 输出：重排后的64位数组
 */ 
int IP_1_table[64] = { 40, 8, 48, 16, 56, 24, 64, 32, 
                     39, 7, 47, 15, 55, 23, 63, 31,
                     38, 6, 46, 14, 54, 22, 62, 30,
                     37, 5, 45, 13, 53, 21, 61, 29,
                     36, 4, 44, 12, 52, 20, 60, 28,
                     35, 3, 43, 11, 51, 19, 59, 27,
                     34, 2, 42, 10, 50, 18, 58, 26,
                     33, 1, 41, 9, 49, 17, 57, 25
};

void IP_1(int in[], int out[]) {
    for (int i = 0; i < 64; ++i) {
        int index = IP_1_table[i] - 1;
        out[i] = in[index];
    }
}

/*
void test_IP_1() {
    int in[64];
    for (int i = 0; i < 64; ++i) {
        in[i] = i + 1;
    }
    int out[64];
    IP_1(in, out);
    cout << " test for IP_1 " << endl;
    for (int i = 0; i < 64; ++i) {
        cout << out[i] << " ";
    }
}
*/

//====================================================================================================

//加密

/*
 * DES加密
 * 输入：64位明文in，64位密钥K
 * 输出：64位密文out
 */ 
void encrypt(int in[64], int K[64], int out[]) {
    int IP_res[64];
    IP(in, IP_res);
    int interate_res[64];
    interate_en(IP_res, K, interate_res);
    int W_res[64];
    W(interate_res, W_res);
    IP_1(W_res, out);
}


//解密

/*
 * DES解密
 * 输入：64位密文in，64位密钥K
 * 输出：64位明文out
 */ 
void decrypt(int in[64], int K[64], int out[]) {
    int IP_res[64];
    IP(in, IP_res);
    int interate_res[64];
    interate_de(IP_res, K, interate_res);
    int W_res[64];
    W(interate_res, W_res);
    IP_1(W_res, out);
}

//==========================================================================================

//读取并处理

/*
 * 文件读取
 * 输入：txt文件，全局变量
 * 输出：读取的二维字符数组，全局变量
 */ 
void ReadText(char *path) {
    char buf[MAX_LINE];
    FILE *fp;
    int len;

    if ((fp = fopen(path, "r")) == NULL)
    {
        perror("fail to read");
        exit(1);
    }

    size = 0;

    while (fgets(inputTexts[size], MAX_LINE, fp) != NULL)
    {
        len = strlen(inputTexts[size]);
        char a[10];
        //cout << size << " " << len << endl;
        fgets(a, 10, fp);
        if (inputTexts[size][len - 1] == '\n')
            inputTexts[size][len - 1] = '\0'; /*去掉换行符*/
        else                                  // 可能末尾没有换行符
            inputTexts[size][len] = '\0';
        // printf("%s %d \n", inputTexts[size], len - 1);
        size++;
    }

    fclose(fp);

    return;
}


/*
 * 数据处理
 * 输入：读取的二维字符数组，全局变量
 * 输出：处理后的二维整型数组
 */ 
int manageText() {
    for (int i = 0; i < size - 1; ++i) {
        for (int j = 0; j < 64; ++j) {
            input[i][j] = inputTexts[i][j] - 48; 
        }
    }

    int len = strlen(inputTexts[size-1]);
    if (len % 8 != 0) {
        return 0;
    }
    if (len == 64) {
       for (int i = 0; i < 64; ++i) {
           input[size-1][i] = inputTexts[size-1][i] - 48;
       }
       //另起一行赋值08
       //printf("另取一行赋值08\n");
       for (int i = 0; i < 64; ++i) {
           if ((i+3) % 8 == 0) input[size][i] = 1;
           else input[size][i] = 0;
       }
       size++;
       return 1;
    }
    int num;//填充的字节数目
    num = 8 - len / 8;
    int num_1 = num;
    int seq[8]; //每个字节填充的序列
    for (int i = 7; i > -1; --i) {
        seq[i] = num % 2;
        num = num / 2;
    }

    for (int i = 0; i < len; ++i) {
        input[size-1][i] = inputTexts[size-1][i] - 48;
    }

    int index = len;
    for (int i = 0; i < num_1; ++i) {
        for (int j = 0; j < 8; ++j) {
            input[size-1][index] = seq[j];
            index++;
        }
    }
    return 1;


    
}


// int main() {
//     int K[64] = { 1, 0, 1, 1, 0, 1, 0, 0,
//                   0, 1, 1, 1, 0, 0, 0, 1,
//                   1, 0, 0, 0, 1, 1, 0, 1,
//                   0, 1, 1, 0, 1, 0, 1, 0,
//                   0, 0, 1, 1, 0, 1, 0, 1,
//                   1, 0, 0, 1, 1, 0, 1, 0,
//                   0, 1, 1, 1, 0, 0, 1, 0,
//                   1, 1, 1, 1, 0, 0, 0, 0 
//     };

//     char path[] = "1.txt";

//     ReadText(path);
//     printf("size: %d\n", size);
//     int temp = manageText();

//     if (temp == 0) {
//         printf("Incorrect plaintext input format!\n");
//         return 0;
//     }
//     printf("size: %d\n", size);

//     printf("encrypt==========================================\n");
//     int cipher[size][64];
//     for (int i = 0; i < size; ++i) {
//         encrypt(input[i], K, cipher[i]);
//     }

//     for (int i = 0; i < size; ++i) {
//         for (int j = 0; j < 64; ++j) {
//             printf("%d ", cipher[i][j]);
//         }
//         printf("\n");
//     }
//     printf("decrypt==========================================\n");
//     int res[size][64];
//     for (int i = 0; i < size; ++i) {
//         decrypt(cipher[i], K, res[i]);
//     }
//     for (int i = 0; i < size; ++i) {
//         for (int j = 0; j < 64; ++j) {
//             printf("%d ", res[i][j]);
//         }
//         printf("\n");
//     }

//     printf("plaintext========================================\n");
//     for (int i = 0; i < size; ++i) {
//         for (int j = 0; j < 64; ++j) {
//             printf("%d ", input[i][j]);
//         }
//         printf("\n");
//     }
//     return 0;
// }



